package org.reliablesource.pleiades;

import java.util.LinkedList;
import java.util.List;

import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableColorProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.ITreePathContentProvider;
import org.eclipse.jface.viewers.ITreePathLabelProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerLabel;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.part.ViewPart;

/**
 * @since 3.2
 * 
 */
public class CommentView extends ViewPart implements ISelectionListener {

	public static final String ID = IBrowserConstants.PLUGIN_ID
			+ IBrowserConstants.VIEW + "comments";

	private TreeViewer viewer;
	private final List<ReliableSimpleComment> commentList = new LinkedList<ReliableSimpleComment>();

	final static String COLS[] = { "Comment", "Replies" };

	final static int Comments = 0;
	final static int Replies = 1;
	private ISelection input;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	public void createPartControl(Composite _parent) {

		viewer = new TreeViewer(_parent);

		Tree _tree = viewer.getTree();
		TreeColumn _col = null;
		_tree.setHeaderVisible(true);
		_tree.setLinesVisible(true);
		for (int i = 0; i < COLS.length; i++) {
			_col = new TreeColumn(_tree, SWT.LEFT);
			_col.setMoveable(true);
			_col.setResizable(true);
			_col.setText(COLS[i]);
			_col.pack();
		}

		_tree.setLayoutDeferred(true);

		class SemanticBindingContentProvider implements
				ITreePathContentProvider, ITreeContentProvider {
			public void dispose() {
			}

			public void inputChanged(Viewer _viewer, Object _oldInput,
					Object _newInput) {
			}

			public Object[] getElements(Object _inputElement) {
				return getChildren(_inputElement);
			}

			public Object[] getChildren(Object _parentElement) {
				if (_parentElement instanceof List) {
					return ((List) _parentElement).toArray();
				}

				else if (_parentElement instanceof ReliableSimpleComment) {
					ReliableSimpleComment _comment = (ReliableSimpleComment) _parentElement;

					String _key = _comment.getBinding().getParent().getId();

					System.err.println("***********" + _key);
					return BrowserPlugin.getDefault().getResourceCommentList(
							_key);
				}

				return new Object[0];
			}

			public Object getParent(Object _element) {

				if (_element instanceof ReliableUser) {
					ReliableUser _user = (ReliableUser) _element;
					int _nComments = _user.getCreatedComments().length;
					if (_nComments > 0)
						return true;
				}

				else if (_element instanceof ReliableSimpleComment) {
					// ReliableSimpleComment _comment = (ReliableSimpleComment)
					// _element;
					// return _comment.get
				}

				if (_element instanceof ReliableResource) {
					ReliableResource _rsrc = (ReliableResource) _element;
					return _rsrc.getParent();
				}
				return new Object[0];
			}

			public boolean hasChildren(Object _element) {

				if (_element instanceof ReliableSimpleComment) {
					ReliableSimpleComment _comment = (ReliableSimpleComment) _element;
					int _nReplies = _comment.getReplies().length;
					if (_nReplies > 0)
						return true;
				}
				return false;
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.ITreePathContentProvider#getChildren(org.eclipse.jface.viewers.TreePath)
			 */
			public Object[] getChildren(TreePath _parentPath) {
				return getChildren(_parentPath.getFirstSegment());
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.ITreePathContentProvider#getParents(java.lang.Object)
			 */
			public TreePath[] getParents(Object _element) {

				if (_element instanceof ReliableSimpleComment) {
					ReliableSimpleComment _comment = (ReliableSimpleComment) _element;
					// _comment.getAuthor();
					_comment.getBinding();
				}

				if (_element instanceof ReliableResource) {
					ReliableResource _rsrc = (ReliableResource) _element;
				}
				return new TreePath[0];
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.ITreePathContentProvider#hasChildren(org.eclipse.jface.viewers.TreePath)
			 */
			public boolean hasChildren(TreePath _path) {
				return hasChildren(_path.getFirstSegment());
			}
		}

		viewer.setContentProvider(new SemanticBindingContentProvider());

		class SemanticBindingLabelProvider implements ITableColorProvider,
				ITableLabelProvider, ITreePathLabelProvider {

			private final List<ILabelProviderListener> labelProviderListenerList = new LinkedList<ILabelProviderListener>();

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.ITableColorProvider#getBackground(java.lang.Object,
			 *      int)
			 */
			public Color getBackground(Object _element, int _columnIndex) {
				return null;
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.ITableColorProvider#getForeground(java.lang.Object,
			 *      int)
			 */
			public Color getForeground(Object _element, int _columnIndex) {
				return null;
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object,
			 *      int)
			 */
			public Image getColumnImage(Object _element, int _columnIndex) {
				return null;
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object,
			 *      int)
			 */
			public String getColumnText(Object _element, int _columnIndex) {
				StringBuffer _retVal = new StringBuffer();
				switch (_columnIndex) {
				case Comments:

					if (_element instanceof ReliableSimpleComment) {
						String _text = ((ReliableSimpleComment) _element)
								.getCommentText();

						// BrowserPlugin.getDefault().getResourceCommentList(_text)
						_retVal.append(_text);
					}
					break;
				case Replies:
					if (_element instanceof ReliableSimpleComment) {
						String _text = ((ReliableSimpleComment) _element)
								.getCommentText();
						_retVal.append(_text);
					}
					break;
				}
				return _retVal.toString().trim();
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
			 */
			public void addListener(final ILabelProviderListener _listener) {
				if (null != _listener)
					if (!labelProviderListenerList.contains(_listener))
						labelProviderListenerList.add(_listener);
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
			 */
			public void dispose() {
				labelProviderListenerList.clear();
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object,
			 *      java.lang.String)
			 */
			public boolean isLabelProperty(Object _element, String _property) {
				return false;
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
			 */
			public void removeListener(ILabelProviderListener _listener) {
				if (null != _listener)
					if (labelProviderListenerList.contains(_listener))
						labelProviderListenerList.remove(_listener);
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see org.eclipse.jface.viewers.ITreePathLabelProvider#updateLabel(org.eclipse.jface.viewers.ViewerLabel,
			 *      org.eclipse.jface.viewers.TreePath)
			 */
			public void updateLabel(ViewerLabel _label, TreePath _elementPath) {

			}

		}

		viewer.setLabelProvider(new SemanticBindingLabelProvider());
		viewer.setInput(commentList);
		getSite().getWorkbenchWindow().getSelectionService()
				.addSelectionListener(this);

		getSite().setSelectionProvider(viewer);
		getSite().registerContextMenu(new MenuManager(),
				getSite().getSelectionProvider());

	}

	@Override
	public void setFocus() {
		if (viewer != null)
			if (viewer.getControl() != null)
				viewer.getControl().setFocus();

	}

	/**
	 * 
	 * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart,
	 *      org.eclipse.jface.viewers.ISelection)
	 */
	public void selectionChanged(final IWorkbenchPart _part,
			final ISelection _selection) {

		if (!(_part instanceof SelectedViewPart))
			return;

		if (_selection.equals(StructuredSelection.EMPTY))
			return;

		// if (_selection.equals(input))
		// return;
		//
		// input = _selection;

		if (_selection instanceof IStructuredSelection) {
			ReliableSnippet _selected = (ReliableSnippet) ((IStructuredSelection) _selection)
					.getFirstElement();

			ReliableSimpleComment _comment = new ReliableSimpleComment("dennis");

			_comment.setCommentText("invokedBySelection :  "
					+ _selected.getDate());
			ReliableResource _rsrc = new ReliableResource();
			_rsrc.setContext(_selected);
			_comment.setBinding(_rsrc);

			ReliableResource _resrc = BrowserPlugin.getDefault()
					.getResourceLink(_selected.getParent().getId());
			String _key = _resrc.getId();
			System.err.println(_key);

			commentList.add(_comment);

			ReliableSimpleComment[] _list = BrowserPlugin.getDefault()
					.getResourceCommentList(_key);

			for (int i = 0; i < _list.length; i++)
				if (!commentList.contains(_list[i]))
					commentList.add(_list[i]);

			if (viewer != null)
				viewer.refresh();
		}
	}
}
